20장 strict mode
function foo() {
x = 10;
}
foo();
console.log(x); // ?
위 코드에서 x 변수에 10을 할당하기 위해서 x 변수가 어디에서 선언되었는지 스코프체인
을 통해서 검색함
- foo 함수의 스코프에서 x 변수 선언 검색→ 실패
- foo 함수 컨테스트의 상위 스코프에서 x 변수 선언 검색 → 실패
전역 스코프에도 x 변수 선언 없어서 ReferenceError 발생하나?
→ ❌ 암묵적으로 전역 객체에 x 프로퍼티 동적으로 생성함. 이게 바로암묵적 전역
이런식으로 오류가 발생하기 쉬운 JS 엔진 처리들이 있음.
⇒ strinct mode
를 통해서 문법을 엄격히 적용할 수 있음.
strict mode 적용
- 전역 선두에
'use strict';
추가하면 전체에 strict mode 적용 - 함수 몸체 선두에 추가하면 해당함수와 중첩함수에 strict mode 적용
전역이나 함수 선두말고 중간에 위치시키면 에러발생시키진 않지만 동작 ❌
'use strict';
function foo() {
x = 10; // ReferenceError: x is not defined
}
foo();
function foo2() {
'use strict';
x = 10; // ReferenceError: x is not defined
}
foo2();
전역에 strict mode 적용하는 것 피하자
전역에 strict mode 를 적용시키면 외부 라이브러리를 사용하는 경우 오류를 발생시킬 수 있음.
즉시 실행 함수로 감싸서 스코프 구분하고 그 안에서 strict mode 적용하는게 좋다.
// 즉시 실행 함수의 선두에 strict mode 적용
(function () {
'use strict';
// Do something...
}());
함수 단위로 strict mode 적용하는 것도 피하자
(function () {
// non-strict mode
var lеt = 10; // 에러가 발생하지 않는다.
function foo() {
'use strict';
let = 20; // SyntaxError: Unexpected strict mode reserved word
}
foo();
}());
strict mode 적용된 함수가 참조할 함수 외부의 컨텍스트에 strict mode 적용되지 않아서 생기는 에러
⇒ 즉시실행 함수 단위로 strict mode 적용해라
strict mode 가 발생시키는 에러
- 선언하지 않은 변수를 참조하면 ( 암묵적 전역 )
- delete 연산자로 변수, 매개변수 삭제하면
- 매개변수 이름의 중복
- with 문의 사용
- with 문은 전달된 객체를 스코프 체인에 추가함.
strict mode 적용에 의한 변화
-
일반 함수의 this
- 일반 함수로 호출하면 this 에
undefined
바인딩
(function () { 'use strict'; function foo() { console.log(this); // undefined } foo(); function Foo() { console.log(this); // Foo } new Foo(); }());
- 일반 함수로 호출하면 this 에
-
arguments 객체
- 매개변수에 전달된 인수를 재할당해서 변경해도 반영 안됨.
(function (a) { 'use strict'; // 매개변수에 전달된 인수를 재할당하여 변경 a = 2; // 변경된 인수가 arguments 객체에 반영되지 않는다. console.log(arguments); // { 0: 1, length: 1 } }(1));